<template>
	<view class="content">
		<textarea class="textareas" maxlength="-1" v-model="searchData.codes" :confirm-hold="true" confirm-type="return"
			placeholder="请输入柜号，多个编码之间以换行拼接，禁止输入特殊字符！最多30个设备号" placeholder-style="font-size:28rpx" :rows="6"
			@change.native="keyUp($event)" @input.native="keyInput($event)" @blur.native="keyBlur($event)"></textarea>
		<view class="search_btns">
			<button type="primary" size="mini" @click="doSearch">搜索</button>
		</view>

		<uni-card :isFull="true">
			<view class="search_codes">
				<view class="parts">
					<text>
						升级部件
					</text>
					<picker class="picker-select" @change="bindPickerChange($event, index)" :range="partOption"
						range-key="name">
						<text class="uni-input">{{currentPart.name?currentPart.name:'请选择'}}</text>
						<uni-icons class="down-icon" type="bottom" size="14"></uni-icons>
					</picker>
				</view>
				<button class="operate-btn" type="primary" size="mini" @click="isBatchUpdate"
					v-if="permission('applet:batchupgrade:upgrade')">批量升级</button>
			</view>

			<view class="search_codes">
				<view class="parts">
					<text>
						版本
					</text>
					<picker class="picker-select" :disabled="!currentPart.code || versionOption.length==0"
						@click="changeVersion" @change="versionPickerChange($event, index)" :range="versionOption"
						range-key="version">
						<text class="uni-input">{{currentVersion.version?currentVersion.version:'请选择'}}</text>
						<uni-icons class="down-icon" type="bottom" size="14"></uni-icons>
					</picker>
					<uni-icons @click="showHelp" color="#707070" class="help_icon" type="help" size="24">
					</uni-icons>
				</view>
				<button class="operate-btn" type="primary" size="mini" @click="isSearchVersion()">批量查询版本</button>
			</view>
		</uni-card>

		<view class="tips">
			升级后版本号获取需手动刷新,如退出本页面请至升级记录或者查询功能中查询版本信息。
		</view>

		<view class="table-title" v-if="nofoundList.length>0" style="color: red;">
			未搜索到的设备列表
		</view>
		<uni-list class="nofoundList" v-if="nofoundList.length>0">
			<uni-list-item title="编码">
				<template slot="footer">
					<text style="font-size: 24rpx;">复制</text>
				</template>
			</uni-list-item>
			<uni-list-item v-for="(item,index) in nofoundList" :key="index" :title="item">
				<template slot="footer">
					<text class="iconfont icon-copy" @click="isCopy(item)" style="border: none;"></text>
				</template>
			</uni-list-item>
		</uni-list>

		<boxList :tableData="tableData" :page="page" :total="total" @resendParam="resendParam"
			@checkedChange="checkedChange" @isSearchVersion="isSearchVersion" @changePage="changePage"></boxList>
	</view>
</template>

<script>
	import {
		equipment,
		partType,
		softwareVersion,
		updated
	} from "@/api/my.js";
	import {
		removeNullUndefined,
		doCopy,
		unique
	} from "@/common/index.js";
	import {
		mapState,
	} from 'vuex';
	import {
		permission
	} from "@/common/permission.js";
	import boxList from "@/component/boxList.vue";
	export default {
		components: {
			boxList
		},
		data() {
			return {
				searchData: {
					codes: "",
				},
				tableData: [],
				// 每页数据量
				size: 30,
				// 当前页
				page: 1,
				total: 0,

				partOption: [], //部件
				currentPart: {},
				currentVersion: {},
				versionOption: [], //版本
				versionCodes: [], //查询版本codes

				equipIds: [], //所选设备ids
				nofoundList: [], //未找到code列表
				permission: permission,
			}
		},
		filters: {
			formatVersion(arr) {
				if (arr && arr.length > 0) {
					let arrayTwo = Object.values(
						arr.reduce((res, item) => {
							res[item.partType] ?
								res[item.partType].push(item) :
								(res[item.partType] = [item]);
							return res;
						}, {})
					);
					let jsons = "";
					arrayTwo.map((item, index) => {
						jsons += item[0].partTypeName;
						item.filter((qq, inx) => {
							jsons += qq.version;
							if (inx < item.length - 1) jsons += " | ";
						});
						if (index < arrayTwo.length - 1) jsons += "；";
					});
					return jsons;
				} else {
					return "";
				}
			}
		},
		computed: {
			...mapState(['enums', 'equipTypeCode'])
		},

		onLoad() {
			this.getPartType();
		},
		methods: {
			getDataList() {
				let param = {
					...this.searchData
				};

				if (param.codes) {
					param.codes = param.codes.split("\n").filter(item => item);
				}
				if (param.codes.length == 1) {
					param.code = param.codes[0];
					delete param.codes;
				}

				this.nofoundList = [];
				if (param.codes && param.codes.length > 30) {
					this.$Toast.none('最多30个设备号～');
					return;
				}
				this.$Toast.loading('加载中~');
				equipment('/version/list', 'post', {
					...removeNullUndefined(Object.assign(param, {
						pageNum: this.page,
						pageSize: this.size,
						equipTypeCode: this.equipTypeCode
					}))
				}).then(res => {
					if (res.code == 200) {
						this.tableData = res.data;

						this.total = +res.total;
						this.tableData.forEach(item => item.checked = false);

						// 查找未搜索到的设备code
						if (param.codes) {
							this.nofoundList = param.codes.filter(item => !this.tableData.some(ele => ele.code
								.toLowerCase() ==
								item.toLowerCase()));
						} else if (param.code) {
							this.nofoundList = this.tableData.length == 0 ? [param.code] : [];
						}
					}
				}).finally(() => uni.hideLoading());
			},
			// 分页
			changePage(e) {
				this.page = e;
				this.getDataList();
			},
			// tableData改变
			checkedChange(val) {
				this.tableData = val;
			},
			// 获取部件
			getPartType() {
				partType(`/list?equipTypeCode=${this.equipTypeCode}`, 'get').then(res => {
					if (res.code == 200) {
						this.partOption = res.data;
					}
				});
			},
			// 搜索
			doSearch() {
				let param = {
					...this.searchData
				};

				if (param.codes) {
					param.codes = param.codes.split("\n").filter(item => item);
				}
				if (param.codes.length == 0) {
					this.$Toast.none('请输入柜号');
					return;
				}
				this.getDataList();
			},
			// 复制
			isCopy(item) {
				doCopy(item);
			},

			//限制输入特殊字符
			keyUp(e) {
				let str = e.target.value.replace(
					/[`~!@#$%^&*()_\-+=<>?:"{}|.\;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘’，。、]/g,
					""
				);
				e.target.value = str;
				this.searchData.codes = str;
			},
			// 只能输入汉字、英文、数字
			keyInput(e) {
				let str = e.target.value.replace(/[^\a-\z\A-\Z0-9\n/]/g, "");
				e.target.value = str;
				this.searchData.codes = str;
			},
			keyBlur() {
				let codes = JSON.parse(JSON.stringify(this.searchData.codes));
				codes = unique(codes.split("\n"));
				this.searchData.codes = codes.join('\n');
			},
			bindPickerChange(e) {
				let index = e.detail.value;
				let current = this.partOption[index];
				this.currentPart = current;
				this.getVersion();
			},
			versionPickerChange(e) {
				let index = e.detail.value;
				let current = this.versionOption[index];
				this.currentVersion = current;
			},
			changeVersion() {
				if (!this.currentPart.code) {
					this.$Toast.none("请先选择升级部件~");
					return;
				} else if (this.versionOption.length == 0) {
					this.$Toast.none("暂无数据~");
					return;
				}
			},
			// 获取版本
			getVersion() {
				this.currentVersion = {};
				softwareVersion(`/all?partType=${this.currentPart.code}`, 'get').then(res => {
					if (res.code == 200) {
						this.versionOption = res.data;
					}
				});
			},
			// 批量升级
			isBatchUpdate(type) {
				// 选中设备
				this.equipIds = this.tableData.filter(item => item.checked).map(p => {
					return p.id
				});
				let onlineList = this.tableData.filter(item => item.checked && item.isAllowOperate); //可操作设备

				if (this.tableData.length == 0) {
					this.$Toast.none('暂无设备，请先搜索~');
					return;
				} else if (this.equipIds.length == 0) {
					this.$Toast.none('请勾选需要升级的设备');
					return;
				} else if (this.equipIds.length > 0 && onlineList.length == 0) {
					this.$Toast.none('设备离线/禁用不可操作！');
					return;
				} else if (!this.currentPart.code || !this.currentVersion.id) {
					this.$Toast.none('请选择部件及版本');
					return;
				}

				let that = this;
				let msg = '';
				if (onlineList.length < this.equipIds.length) { //选中设备包含离线
					msg = "离线/禁用设备不可操作，已自动过滤！"
				}
				uni.showModal({
					title: '提示',
					content: this.equipIds.length > 1 ? `${msg}确定要批量升级吗？` : `${msg}确定要升级吗？`,
					success(res) {
						if (res.confirm) {
							that.dividerGroup(type);
						}
					}
				})
			},
			dividerGroup(type) {
				let that = this;
				if (!type) { //1,重新升级 else：批次
					this.tableData.forEach((item, inx) => {
						this.$set(this.tableData[inx], 'resultReason', null);
						this.$set(this.tableData[inx], 'resultStatus', null);
					})
				}

				let arr = this.tableData.filter(item => item.checked && item.isAllowOperate).map(p => {
					return p.id
				});

				let arrr = [];
				let result = arr.reduce(function(pre, item, index, arr) {
					let begin = index * 5;
					let end = begin + 5;
					let res = arr.slice(begin, end);
					if (res.length != 0) {
						arrr[index] = res;
					}
					return arrr;
				}, []);

				this.$Toast.loading('升级中~');
				// 5个一组,每次下发5个
				(function(arr) {
					let i = 0,
						length = result.length;
					(function a() {
						let timer = setTimeout(function() {
							let lng = i == length - 1 ? true : false;
							that.doUpdate(result[i++], lng);
							i < length && a();
						}, 300);
					}())
				}(result));
			},
			// 升级
			doUpdate(arr, isLast) {
				// isLast 是否最后一组
				for (let i = 0; i < arr.length; i++) {
					updated(`/upgrade/${arr[i]}?softwareVersionId=${this.currentVersion.id}`,
							'post').then(res => {
							let datas = res.data;
							let inx = this.tableData.findIndex(item => item.id == arr[i]);
							this.$set(this.tableData[inx], 'equipSoftwareVersions', datas
								.equipSoftwareVersions);
							this.$set(this.tableData[inx], 'resultReason', datas.reason);
							this.$set(this.tableData[inx], 'resultStatus', datas.status);
						}).finally(() => {
							if (isLast && i == arr.length - 1) {
								this.$Toast.none('操作完成~');
							}
						})
						.catch(err => {
							let inx = this.tableData.findIndex(item => item.id == arr[i]);
							this.$set(this.tableData[inx], 'resultStatus', 3);
							this.$set(this.tableData[inx], 'resultReason', err.message);
						});
				}
			},
			// 查询版本
			isSearchVersion(e) {
				if (e) {
					this.versionCodes = [e];
				} else {
					this.versionCodes = this.tableData.filter(item => item.checked).map(p => {
						return p.code
					});
				}
				let onlineList = this.tableData.filter(item => item.checked && item.isAllowOperate); //可操作设备

				if (this.versionCodes.length > 0 && onlineList.length == 0) {
					this.$Toast.none('设备离线/禁用不可操作！');
					return;
				}
				if (!this.currentPart.code) {
					this.$Toast.none('请选择部件类型');
					return;
				} else if (this.versionCodes.length == 0) {
					this.$Toast.none('请勾选需要查询的设备');
					return;
				}
				let that = this;
				let msg = '';
				if (onlineList.length < this.equipIds.length) { //选中设备包含离线
					msg = "离线/禁用设备不可操作，已自动过滤！"
				}
				uni.showModal({
					title: '提示',
					content: this.versionCodes.length > 1 ? `${msg}确定要批量查询版本吗？` : `${msg}确定要查询版本吗？`,
					success(res) {
						if (res.confirm) {
							that.doSearchUpdate();
						}
					}
				})
			},
			doSearchUpdate() {
				this.$Toast.loading('查询中~');

				let equipIds = this.tableData.filter(item => item.checked && item.isAllowOperate).map(p => {
					return p.id
				});

				equipment(`/version/all?ids=${equipIds.join(',')}&partTypes=${this.currentPart.code}`, 'post').then(
					res => {
						if (res.code == 200) {
							let datas = res.data;
							if (datas && datas.length > 0) {
								datas.forEach(item => {
									this.tableData.forEach((pp, inx) => {
										if (item.code == pp.code) {
											this.$set(this.tableData[inx], 'equipSoftwareVersions',
												item.equipSoftwareVersions);
										}
									})
								})
							}
						}
					}).finally(() => uni.hideLoading())
			},

			showHelp() {
				if (!this.currentVersion.id) {
					this.$Toast.none('请选择升级版本');
					return;
				}
				uni.showModal({
					title: '升级内容',
					content: this.currentVersion.remark,
					showCancel: false,
					showConfirm: false,
					success: function(res) {
						if (res.confirm) {} else if (res.cancel) {}
					}
				});
			},
			// 重新升级
			resendParam(e) {
				this.isBatchUpdate(e);
			},
		},
	}
</script>

<style lang="scss" scoped>
	@import "@/static/css/common";
	@import "@/static/iconfont.css";
	@import "@/static/css/main.scss";

	.content {
		padding: 10rpx 20rpx;
		box-sizing: border-box;
	}

	.icon-copy {
		font-size: 48rpx;
		color: #999999;
		border-bottom: 2rpx solid #dfdfdf;
		padding-bottom: 22rpx;
		margin-bottom: 10rpx;
	}

	.search_btns {
		text-align: right;
		margin: 10rpx 0 0;
	}

	button,button:focus,button:hover {
		background-color: #51b7b9;
	}

	.textareas {
		box-sizing: border-box;
		width: 100%;
		border: 2rpx solid #E5E5E5;
		padding: 10rpx;
		word-break: break-all;
		word-wrap: break-word;
	}

	.part_check {
		transform: scale(0.7);
	}

	.parts {
		color: #333333;
		font-size: 28rpx;
		margin: 10rpx 0;
		border-bottom: 2rpx solid #efefef;
		padding-bottom: 20rpx;
		@include flexLayout(center, flex-start);

		text {
			margin-right: 20rpx;
		}

		.help_icon {
			margin-left: 30rpx;
		}
	}

	.table-title {
		margin: 20rpx 0;
		color: #333333;
		font-size: 32rpx;
		font-weight: 500;
	}

	.search_codes {
		@include flexLayout(center, space-between);

		button {
			margin: 0;
		}
		.operate-btn{
			position: relative;
			right: -20rpx;
		}
	}

	.tips {
		color: #f56c6c;
		font-size: 28rpx;
		margin: 20rpx 0;
	}

	.nodata {
		margin-top: 20%;
	}

	/deep/ .uni-list-item__container {
		padding: 16rpx 20rpx;
	}

	/deep/ .uni-card .uni-card__content {
		padding: 0 !important;
	}
</style>